package com.lee.forum.controller;

import com.lee.forum.common.AppResult;
import com.lee.forum.common.ResultCode;
import com.lee.forum.config.AppConfig;
import com.lee.forum.config.EditorJson;
import com.lee.forum.exception.ApplicationException;
import com.lee.forum.model.Article;
import com.lee.forum.model.Board;
import com.lee.forum.model.PageResult;
import com.lee.forum.model.User;
import com.lee.forum.services.IArticleService;
import com.lee.forum.services.IBoardService;
import com.lee.forum.services.IUserService;
import com.lee.forum.utils.UUIDUtil;
import com.sun.istack.internal.NotNull;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: lishuo
 * Date: 2023-09-30
 * Time: 23:49
 */
@Api(tags = "文章接口")
@Slf4j
@RestController
@RequestMapping("/article")
public class ArticleController {

    // 从配置文件中读取
    @Value("${forum.mdeditor.url}")
    private String mdeditorUrl;

    @Value("${forum.mdeditormapper.url}")
    private String mdeditormapperUrl;


    @Resource
    private IArticleService articleService;
    @Resource
    private IBoardService boardService;
    @Resource
    private IUserService userService;

    // 带有分页功能的文章列表页
    @ApiOperation("获取有效帖子列表(分页)")
    @GetMapping("/getlistbypage")
    public AppResult<PageResult> getListByPage(@ApiParam("板块Id") @RequestParam(value = "boardId",required = false) Long boardId,
                                         @ApiParam("页号") @RequestParam(value = "pIndex",defaultValue = "1",required = false) Integer pIndex,
                                         @ApiParam("每页大小") @RequestParam(value = "pSize",defaultValue = "10",required = false) Integer pSize) {
        // 分页思路1：select ... from articles where boardId = ? limit finalLimit offset finalOffset
        // 分页思路2：使用分页插件 PageHelper
        // 3.定义结果集
        PageResult pageResult = null;
        // 4.查询
        pageResult = articleService.listByPage(pIndex, pSize, boardId);
        // 5.返回结果
        return AppResult.success(pageResult);
    }

    /**
     * 发布新帖
     * @param request 请求
     * @param boardId 板块Id
     * @param title 帖子标题
     * @param content 帖子内容
     * @return
     */
    @ApiOperation("发布新帖")
    @PostMapping("/create")
    public AppResult create (HttpServletRequest request,
                             @ApiParam("板块Id") @RequestParam("boardId") @NotNull Integer boardId,
                             @ApiParam("帖子标题") @RequestParam("title") @NotNull String title,
                             @ApiParam("帖子内容") @RequestParam("content") @NotNull String content) {
        // 1.校验用户是否被禁言
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION_KEY);
        if (user.getState() == 1) {
            // 返回禁言信息
            return AppResult.failed(ResultCode.FAILED_USER_BANNED);
        }
        // 2.校验板块信息是否有效
        Board board = boardService.selectById(Long.valueOf(boardId));
        if (board == null || board.getState() == 1 || board.getDeleteState() == 1) {
            // 打印日志
            log.warn(ResultCode.FAILED_BOARD_STATUS.toString());
            // 返回错误状态信息
            return AppResult.failed(ResultCode.FAILED_BOARD_STATUS);
        }
        // 3.封装文章对象
        Article article = new Article();
        article.setBoarId(Long.valueOf(boardId)); // 板块Id
        article.setTitle(title); // 标题
        article.setContent(content); // 正文
        article.setUserId(user.getId()); // 作者Id
        // 4.调用Service层
        articleService.create(article);
        // 5.成功响应
        return AppResult.success();
    }

    @ApiOperation("获取有效帖子列表")
    @GetMapping("/getAllBoardList")
    public AppResult<List<Article>> getAllBoardList(
            @ApiParam("板块Id") @RequestParam(value = "boardId",required = false) Long boardId) {
        // 定义结果集
        List<Article> articles;
        if (boardId == null) {
            // 1.如果boardId为null,即未传参数，默认获取所有帖子
            // 调用service查询所有帖子
            articles = articleService.selectAll();

        } else {
            // 2.如果boardId不为null，则获取指定板块下的所有帖子
            articles = articleService.selectAllByBoardId(boardId);
        }
        // 判断帖子是否有效
        if (articles == null) {
            articles = new LinkedList<>();
        }
        // 返回结果
        return AppResult.success(articles);
    }

    @ApiOperation("获取帖子详情")
    @GetMapping("/details")
    public AppResult<Article> getDetails(HttpServletRequest request
            ,@ApiParam("帖子Id") @RequestParam("id") @NotNull Long id) {
        // 1.获取session信息
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(AppConfig.USER_SESSION_KEY);
        // 2.调用service获取帖子详情
        Article article = articleService.selectDetailById(id);
        // 3.判断帖子是否有效
        if (article == null) {
            // 打印日志
            log.warn(ResultCode.ERROR_IS_NULL.toString()+"article id = "+id);
            // 返回错误信息
            return AppResult.failed(ResultCode.ERROR_IS_NULL);
        }
            // 4.判断是否为作者
        if (user.getId() == article.getUserId()) {
            article.setOwn(true);
        }
        // 5.返回结果
        return AppResult.success(article);
    }

    @ApiOperation("修改帖子")
    @PostMapping("/modify")
    public AppResult modify(HttpServletRequest request,
                            @ApiParam("帖子Id") @RequestParam("id") @NotNull Long id,
                            @ApiParam("帖子标题") @RequestParam("title") @NotNull String title,
                            @ApiParam("帖子正文") @RequestParam("content") @NotNull String content) {
        // 1.获取当前登录用户
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(AppConfig.USER_SESSION_KEY);
        // 2.检查用户状态(是否被禁言)
        if (user.getState() == 1) {
            // 打印日志
            log.warn(ResultCode.FAILED_USER_BANNED.toString()+"user id = "+user.getId());
            // 返回错误信息
            return AppResult.failed(ResultCode.FAILED_USER_BANNED);
        }
        // 3.获取并检查文章是否有效
        Article article = articleService.selectById(id);
        if (article == null) {
            // 打印日志
            log.warn(ResultCode.ERROR_IS_NULL.toString()+"article id = "+id);
            // 返回错误信息
            return AppResult.failed(ResultCode.ERROR_IS_NULL);
        }
        // 4.判断用户是否为作者
        if (user.getId() != article.getUserId()) {
            // 打印日志
            log.warn(ResultCode.FAILED_UNAUTHORIZED+"user id = "+user.getId());
            // 返回错误信息
            return AppResult.failed(ResultCode.FAILED_UNAUTHORIZED);
        }
        // 5.判断文章状态是否正常
        if (article.getState() == 1 || article.getDeleteState() == 1) {
            // 打印日志
            log.warn(ResultCode.FAILED_ARTICLE_STATUS.toString()+"article id = "+id);
            // 返回错误信息
            return AppResult.failed(ResultCode.FAILED_ARTICLE_STATUS);
        }
        // 6.调用service
        articleService.modify(id, title, content);
        // 7.返回正确信息
        return AppResult.success();
    }

    @ApiOperation("帖子点赞")
    @PostMapping("/thumbsUp")
    public AppResult thumbsUpById(HttpServletRequest request,
                                  @ApiParam("帖子Id") @RequestParam("id") @NotNull Long id) {
        // 1.获取当前登录用户
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(AppConfig.USER_SESSION_KEY);
        // 2.判断用户是否被禁言
        if (user.getState() == 1) {
            // 打印日志
            log.warn(ResultCode.FAILED_USER_BANNED.toString()+"user id = "+user.getId());
            // 返回错误信息
            return AppResult.failed(ResultCode.FAILED_USER_BANNED);
        }
        // 3.调用service查询并判断文章是否有效
        Article article = articleService.selectById(id);
        if (article == null || article.getDeleteState() == 1) {
            // 打印日志
            log.warn("帖子不存在 article id = "+id);
            // 返回错误信息
            return AppResult.failed(ResultCode.ERROR_IS_NULL);
        }
        // 帖子状态异常
        if (article.getState() == 1) {
            // 打印日志
            log.warn(ResultCode.FAILED_ARTICLE_STATUS+"article id = "+id);
            // 返回错误信息
            return AppResult.failed(ResultCode.FAILED_ARTICLE_STATUS);
        }
        // 4.调用service
        articleService.thumbsUpById(id);
        // 5.返回正确信息
        return AppResult.success();
    }

    @ApiOperation("删除帖子")
    @PostMapping("/delete")
    public AppResult deleteById(HttpServletRequest request,
                                @ApiParam("帖子Id") @RequestParam("id") @NotNull Long id) {
        // 1.获取当前登录用户信息
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION_KEY);
        // 判断当前用户是否被禁言
        if (user.getState() == 1) {
            // 打印日志
            log.warn(ResultCode.FAILED_USER_BANNED.toString()+"user id = "+user.getId());
            // 返回错误信息
            return AppResult.failed(ResultCode.FAILED_USER_BANNED);
        }
        // 2.根据id获取帖子信息并判断文章是否有效
        Article article = articleService.selectById(id);
        // 判断帖子是否已删除
        if (article == null || article.getDeleteState() == 1) {
            // 打印日志
            log.warn("帖子不存在 article id = "+id);
            // 返回错误信息
            return AppResult.failed(ResultCode.ERROR_IS_NULL);
        }
        // 判断帖子状态
        if (article.getState() == 1) {
            // 打印日志
            log.warn(ResultCode.FAILED_ARTICLE_STATUS+"article id = "+id);
            // 返回错误信息
            return AppResult.failed(ResultCode.FAILED_ARTICLE_STATUS);
        }
        // 3.判断是否为作者
        if (user.getId() != article.getUserId()) {
            // 打印日志
            log.warn(ResultCode.FAILED_UNAUTHORIZED+"user id = "+user.getId());
            // 返回错误信息
            return AppResult.failed(ResultCode.FAILED_UNAUTHORIZED);
        }
        // 4.调用service执行更新操作
        articleService.deleteById(id);
        // 5.返回成功信息
        return AppResult.success();
    }

    @ApiOperation("根据用户id获取帖子列表")
    @GetMapping("/getAllByUserId")
    public AppResult<List<Article>> getAllByUserId(HttpServletRequest request,
                                    @ApiParam("用户Id") @RequestParam(value = "userId",required = false)  Long userId) {

        // 1.如果userId为null
        if (userId == null) {
            // 获取当前登录用户
            HttpSession session = request.getSession(false);
            User user = (User) session.getAttribute(AppConfig.USER_SESSION_KEY);
            // 获取当前用户登录Id
            userId = user.getId();
        } else {
            // 2.根据userId判断用户是否存在
            User user = userService.selectById(userId);
            if (user == null) {
                // 打印日志
                log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
                // 返回错误信息
                return AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS);
            }
        }
        // 3.调用service查询当前用户的帖子列表
        List<Article> articles = articleService.selectByUserId(userId);
        // 4.返回结果
        return AppResult.success(articles);
    }

    @ApiOperation("上传博客图片")
    @PostMapping("/editormdImages")
    public EditorJson editormdImages(
            @ApiParam("博客图片") @RequestPart("editormd-image-file") @NotNull MultipartFile file) throws IOException {
        // 1.生成一个唯一 id
        String id = UUIDUtil.UUID_32();
        // 2.获取源文件后缀名
        String suffix = file.getOriginalFilename().
                substring(file.getOriginalFilename().lastIndexOf("."));
        // 判断文件类型是否符合要求（要求文件格式为.png或.jpg）
        if (!suffix.equals(".jpg") && !suffix.equals(".png") ) {
            // 打印日志
            log.warn("文件类型错误");
            // 抛出异常
            throw new ApplicationException(AppResult.failed("文件类型错误"));
        }
        // 4.设置文件完整保存路径
//        String path = "/root/forum1.0/editorImage/"+id+suffix;
//        String path = "D:/forumImage/"+id+suffix;
        String path = mdeditorUrl+id+suffix;

        file.transferTo(new File(path));

        EditorJson editorJson = new EditorJson();
        editorJson.setSuccess(1);
        editorJson.setUrl(mdeditormapperUrl+id+suffix);
        return editorJson;
    }

}
